package com.cw.reduce.filter;

import java.util.Arrays;
import java.util.List;
import java.util.Vector;

public class FoundFilter implements IFilter {
	private static final Integer[] ouheDigit = new Integer[] { 4, 6, 8 };

	private static List ouheList;
	private static final Integer[] primeDigit = new Integer[] { 2, 3, 5, 7 };
	private static List primeList;
	private static String[] sumType = { "=0", "=1", "=2", "=3", "<2", "<3",
			">0", ">1" }; // jo ou
	private static int[] valueBin = new int[4];
	private static String valueString[] = { "10001100", "01001110", "00100111",
			"00010011" };
	static {

		primeList = Arrays.asList(primeDigit);
		ouheList = Arrays.asList(ouheDigit);

		for (int i = 0; i < valueString.length; i++) {

			int sum = 0;
			for (int j = 0; j < valueString[i].length(); j++) {
				if (valueString[i].charAt(j) == '1') {
					sum = (sum << 1) + 1;
				}
				if (valueString[i].charAt(j) == '0') {
					sum = sum << 1;
				}
			}
			valueBin[i] = sum;
		}

	}
	private int type;

	public FoundFilter(int type) {
		this.type = type;
	}

	private int even(int d) {
		if (d % 2 == 0) {
			return 1;
		}
		return 0;
	}

	private int getSum(int value, int input) {
		int sum = 0;
		int[] arrayw = value2arrays(value);
		for (int i = 0; i < 3; i++) {
			if (arrayw[i] == input) {
				sum++;
			}
		}
		return sum;
	}

	private boolean judgeDigit(int value, String select) {
		int sel = 1;
		for (int i = 0; i < sumType.length; i++) {
			if (sumType[i].equals(select)) {
				sel = sel << (7 - i);
				break;
			}
		}
		if ((valueBin[value] & sel) == sel) {
			return true;
		}
		return false;
	}

	public Vector startFilter(Vector condition, Vector<Integer> target) {
		Vector result = new Vector();
		String condi = (String) condition.elementAt(0);
		switch (type) {
		case 0:
			for (int i = 0; i < target.size(); i++) {
				int value = target.elementAt(i);
				int[] arrayw = value2arrays(value);

				int sumodd = arrayw[0] % 2 + arrayw[1] % 2 + arrayw[2] % 2;
				if (judgeDigit(sumodd, condi)) {
					result.add(value);
				}
			}
			break;
		case 1:
			for (int i = 0; i < target.size(); i++) {
				int value = target.elementAt(i);
				int bw = value / 100;
				int sw = value / 10 % 10;
				int gw = value % 10;
				int sumeven = even(bw) + even(sw) + even(gw);
				if (judgeDigit(sumeven, condi)) {
					result.add(value);
				}
			}
			break;
		case 2:
			for (int i = 0; i < target.size(); i++) {
				int value = target.elementAt(i);
				if (judgeDigit(getSum(value, 0), condi)) {
					result.add(value);
				}
			}
			break;
		case 3:
			for (int i = 0; i < target.size(); i++) {
				int value = target.elementAt(i);
				if (judgeDigit(getSum(value, 1), condi)) {
					result.add(value);
				}
			}
			break;
		case 4:
			for (int i = 0; i < target.size(); i++) {
				int value = target.elementAt(i);
				if (judgeDigit(getSum(value, 9), condi)) {
					result.add(value);
				}
			}
			break;
		case 5:
			for (int i = 0; i < target.size(); i++) {
				int value = target.elementAt(i);
				if (judgeDigit(sumPrime(value, true), condi)) {
					result.add(value);
				}
			}
			break;
		case 6:
			for (int i = 0; i < target.size(); i++) {
				int value = target.elementAt(i);
				if (judgeDigit(sumPrime(value, false), condi)) {
					result.add(value);
				}
			}
			break;
		case 7:
			for (int i = 0; i < target.size(); i++) {
				int value = target.elementAt(i);
				if (judgeDigit(sumBig(value, true), condi)) {
					result.add(value);
				}
			}
			break;
		case 8:
			for (int i = 0; i < target.size(); i++) {
				int value = target.elementAt(i);
				if (judgeDigit(sumBig(value, false), condi)) {
					result.add(value);
				}
			}
			break;
		default:
			result = target;
		}
		return result;
	}

	private int sumBig(int value, boolean big) {
		int sum = 0;
		int[] arrayw = value2arrays(value);
		for (int i = 0; i < 3; i++) {
			if (arrayw[i] > 4) {
				sum++;
			}
		}
		return big ? sum : (3 - sum);
	}

	private int sumPrime(int value, boolean type) {
		int sum = 0;
		int[] arrayw = value2arrays(value);
		for (int i = 0; i < 3; i++) {
			if (type && primeList.contains(arrayw[i])) {
				sum++;
			}
			if (!type && ouheList.contains(arrayw[i])) {
				sum++;
			}
		}
		return sum;
	}

	private int[] value2arrays(int value) {
		int[] arrayw = new int[3];
		arrayw[0] = value / 100;
		arrayw[1] = value / 10 % 10;
		arrayw[2] = value % 10;
		return arrayw;
	}
}
